using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Threading;

namespace BookBarter
{
    public class BookWant : BookInst
    {
        //class variables
        private static List<BookWant> bookWants = new List<BookWant>();
        private Guid wantid;

        //class properties
        public Guid ID
        {
            get { return wantid; }
            private set { wantid = value; }
        }

        //temporary class for testing
        public BookWant(Guid wantid, Condition cond, Person owner, Book book, String nothing)
            : base(cond, owner, book)
        {
            this.ID = wantid;
        }

        //constructor
        private BookWant(Guid wantid, Condition cond, Person owner, Book book)
            : base(cond, owner, book)
        {
            this.ID = wantid;
        }

        /// <summary>
        /// Creates a new book want
        /// </summary>
        /// <param name="owner">owner of the want (who wants it)</param>
        /// <param name="book">book that they want</param>
        /// <param name="cond">condition they want it in</param>
        /// <returns></returns>
        public static BookWant CreateBookWant(Person owner, Book book, Condition cond)
        {
            BookWant newBW = null;

            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //try to run the stored procedure to add the new bookwant
            SqlCommand query = new SqlCommand("EXEC add_book_want @userid, @bookid, @condition", cnx);
            query.Parameters.Add("@userid", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@bookid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@condition", System.Data.SqlDbType.VarChar);
            query.Parameters["@userid"].SqlValue = owner.UserId;
            query.Parameters["@bookid"].SqlValue = book.ID;
            query.Parameters["@condition"].SqlValue = Enum.GetName(typeof(Condition), cond);

            //execute the query
            SqlDataReader result = query.ExecuteReader();
            try
            {
                //set info
                if (result.Read())
                {
                    if (result.IsDBNull(result.GetOrdinal("wantid")))
                        throw new MalformedBookWantRecord("NULL where data is expected for record ID.");
                    newBW = BookWant.GetBookWant(result.GetGuid(result.GetOrdinal("wantid")));
                }
                //else - the creation failed
                else
                    throw new NewBookWantException("The bookwant was not created!");
            }
            finally
            {
                result.Close();
            }
            bookWants.Add(newBW);
            //if we are here... return the book hold object
            return newBW;
        }

        /// <summary>
        /// Gets want information for a specific guid
        /// </summary>
        /// <param name="wantid">the guid of the want</param>
        /// <returns>the bookWant requested</returns>
        public static BookWant GetBookWant(Guid wantid)
        {
            foreach (BookWant bw in bookWants)
                if (bw.ID.Equals(wantid))
                    return bw;
            BookWant newBW = null;

            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //create the query
            SqlCommand query = new SqlCommand("EXEC get_book_want @wantid", cnx);
            query.Parameters.Add("@wantid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters["@wantid"].SqlValue = wantid;

            //execute the query
            SqlDataReader result = query.ExecuteReader();
            try
            {
                //set info
                if (result.Read())
                {
                    Person owner = Person.GetPerson(result.GetString(result.GetOrdinal("userid")));
                    Book book = Book.GetBook(result.GetGuid(result.GetOrdinal("bookid")));
                    Condition cond = BookInst.LookupCondition(result.GetString(result.GetOrdinal("condition")));
                    newBW = new BookWant(wantid, cond, owner, book);
                }
                else
                {
                    throw new NoSuchBookWant("The bookwant does not exist!");
                }
            }
            finally
            {
                result.Close();
            }
            bookWants.Add(newBW);
            //if we are here... return the book hold object
            return newBW;
        }

        /// <summary>
        /// Saves the current object to the database
        /// </summary>
        public void Save()
        {
            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //create query to update the bookwant
            SqlCommand query = new SqlCommand("EXEC update_book_want @wantid, @userid, @bookid, @condition", cnx);
            query.Parameters.Add("@wantid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@userid", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@bookid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@condition", System.Data.SqlDbType.VarChar);
            query.Parameters["@wantid"].SqlValue = this.ID;
            query.Parameters["@userid"].SqlValue = Person.UserId;
            query.Parameters["@bookid"].SqlValue = Book.ID;
            query.Parameters["@condition"].SqlValue = Enum.GetName(typeof(Condition), this.Condition);

            //execute the query
            query.ExecuteNonQuery();
        }


    }
}
